package com.hlt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hlt.context.BaseContext;
import com.hlt.dto.PostCreateDTO;
import com.hlt.dto.PostsPageQueryDTO;
import com.hlt.dto.UserPostsPageQueryDTO;
import com.hlt.dto.SensitivePostQueryDTO;
import com.hlt.entity.Posts;
import com.hlt.entity.SensitiveWordRecord;
import com.hlt.entity.Comments;
import com.hlt.entity.Favorites;
import com.hlt.entity.Likes;
import com.hlt.mapper.PostsMapper;
import com.hlt.mapper.SensitiveWordRecordMapper;
import com.hlt.mapper.CommentsMapper;
import com.hlt.mapper.FavoritesMapper;
import com.hlt.mapper.LikesMapper;
import com.hlt.result.PageResult;
import com.hlt.service.ICategoriesService;
import com.hlt.service.IPostsService;
import com.hlt.utils.SensitiveWordUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hlt.vo.SensitivePostVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.BeanUtils;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lzf
 * @since 2024-11-25
 */
@Service
public class PostsServiceImpl extends ServiceImpl<PostsMapper, Posts> implements IPostsService {

    @Autowired
    private ICategoriesService categoriesService;

    @Autowired
    private SensitiveWordUtil sensitiveWordUtil;

    @Autowired
    private SensitiveWordRecordMapper sensitiveWordRecordMapper;

    @Autowired
    private CommentsMapper commentsMapper;

    @Autowired
    private FavoritesMapper favoritesMapper;

    @Autowired
    private LikesMapper likesMapper;

    // 管理端

    @Override
    public PageResult page(PostsPageQueryDTO postsPageQueryDTO) {
        Page<Posts> page = new Page<>(postsPageQueryDTO.getPageNum(), postsPageQueryDTO.getPageSize());
        LambdaQueryWrapper<Posts> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(postsPageQueryDTO.getTitle() != null, Posts::getTitle, postsPageQueryDTO.getTitle());
        queryWrapper.eq(postsPageQueryDTO.getStatus() != null, Posts::getStatus, postsPageQueryDTO.getStatus());
        page = page(page, queryWrapper);
        return new PageResult(page.getTotal(), page.getRecords());
    }

    // 用户端

    @Override
    public PageResult pageQuery(UserPostsPageQueryDTO userPostsPageQueryDTO) {
        Page<Posts> page = Page.of(userPostsPageQueryDTO.getPage(), userPostsPageQueryDTO.getPageSize());
        LambdaQueryWrapper<Posts> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(Posts::getUserId, userPostsPageQueryDTO.getUserId())
                .orderByDesc(Posts::getCreatedAt);

        // 可扩展其他查询条件
        // if(userPostsPageQueryDTO.getStatus() != null) {
        // queryWrapper.eq(Posts::getStatus, userPostsPageQueryDTO.getStatus());
        // }

        this.page(page, queryWrapper);
        return new PageResult(page.getTotal(), page.getRecords());
    }

    @Override
    @Transactional
    public void save(PostCreateDTO postDTO) {
        // 检测文章标题和内容中的敏感词
        String title = postDTO.getTitle();
        String content = postDTO.getContent();

        // 检测标题和内容中的敏感词
        List<String> titleSensitiveWords = sensitiveWordUtil.findAll(title);
        List<String> contentSensitiveWords = sensitiveWordUtil.findAll(content);

        // 将 DTO 转换为实体
        Posts post = new Posts();
        post.setTitle(postDTO.getTitle());
        post.setContent(postDTO.getContent());
        post.setCategoryId(postDTO.getCategoryId());
        post.setStatus(1); // 默认发布状态

        // 设置用户信息
        Long userId = BaseContext.getCurrentId();
        post.setUserId(Math.toIntExact(userId));

        // 保存文章
        save(post);

        // 如果包含敏感词，记录到敏感词记录表
        if (!titleSensitiveWords.isEmpty() || !contentSensitiveWords.isEmpty()) {
            SensitiveWordRecord record = new SensitiveWordRecord();
            record.setContentId(Long.valueOf(post.getPostId()));
            record.setUserId(Long.valueOf(post.getUserId()));
            record.setContent(content);
            // 合并标题和内容中的敏感词
            Set<String> allSensitiveWords = new HashSet<>();
            allSensitiveWords.addAll(titleSensitiveWords);
            allSensitiveWords.addAll(contentSensitiveWords);
            record.setSensitiveWords(String.join(",", allSensitiveWords));
            record.setCreatedAt(LocalDateTime.now());

            sensitiveWordRecordMapper.insert(record);
        }

        // 更新分类计数
        if (postDTO.getCategoryId() != null) {
            categoriesService.addCount(Long.valueOf(postDTO.getCategoryId()));
        }
    }

    @Override
    @Transactional
    public void updateById(PostCreateDTO postDTO) {
        // 获取现有文章数据
        Posts existingPost = this.getById(postDTO.getPostId());
        if (existingPost == null) {
            throw new RuntimeException("文章不存在");
        }

        // 保留旧分类ID用于计数更新
        Integer oldCategoryId = existingPost.getCategoryId();

        // 更新可修改字段
        Posts updatePost = new Posts();
        updatePost.setPostId(postDTO.getPostId());
        updatePost.setTitle(postDTO.getTitle());
        updatePost.setContent(postDTO.getContent());
        updatePost.setCategoryId(postDTO.getCategoryId());

        // 执行更新
        this.updateById(updatePost);

        // 处理分类计数变化
        handleCategoryCount(oldCategoryId, postDTO.getCategoryId());
    }

    private void handleCategoryCount(Integer oldCategoryId, Integer newCategoryId) {
        if (oldCategoryId != null && !oldCategoryId.equals(newCategoryId)) {
            categoriesService.subCount(Long.valueOf(oldCategoryId));
        }
        if (newCategoryId != null && !newCategoryId.equals(oldCategoryId)) {
            categoriesService.addCount(Long.valueOf(newCategoryId));
        }
    }

    @Override
    public Posts getPostDetail(Integer postId) {
        // 1. 先查询文章是否存在
        Posts post = getById(postId);
        if (post == null) {
            throw new IllegalArgumentException("文章不存在");
        }

        // 2. 使用SQL直接递增浏览量（避免并发问题）
        UpdateWrapper<Posts> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("post_id", postId)
                .setSql("views_count = views_count + 1");
        update(updateWrapper);

        // 3. 返回更新后的文章信息（重新查询确保数据最新）
        return getById(postId);
    }

    @Override
    public PageResult querySensitivePosts(SensitivePostQueryDTO queryDTO) {
        // 构建查询条件
        LambdaQueryWrapper<Posts> queryWrapper = new LambdaQueryWrapper<>();
        if (queryDTO.getUserId() != null) {
            queryWrapper.eq(Posts::getUserId, queryDTO.getUserId());
        }
        if (queryDTO.getPostId() != null) {
            queryWrapper.eq(Posts::getPostId, queryDTO.getPostId());
        }

        // 分页查询
        Page<Posts> page = new Page<>(queryDTO.getPage(), queryDTO.getPageSize());
        Page<Posts> postsPage = page(page, queryWrapper);

        // 过滤包含敏感词的文章并获取敏感词信息
        List<SensitivePostVO> sensitivePosts = postsPage.getRecords().stream()
                .map(post -> {
                    // 检测标题和内容中的敏感词
                    List<String> titleSensitiveWords = sensitiveWordUtil.findAll(post.getTitle());
                    List<String> contentSensitiveWords = sensitiveWordUtil.findAll(post.getContent());

                    // 如果标题或内容包含敏感词，则创建VO对象
                    if (!titleSensitiveWords.isEmpty() || !contentSensitiveWords.isEmpty()) {
                        SensitivePostVO vo = new SensitivePostVO();
                        // 复制Posts的属性
                        BeanUtils.copyProperties(post, vo);
                        // 设置敏感词信息
                        vo.setTitleSensitiveWords(titleSensitiveWords);
                        vo.setContentSensitiveWords(contentSensitiveWords);
                        return vo;
                    }
                    return null;
                })
                .filter(vo -> vo != null) // 过滤掉不包含敏感词的文章
                .collect(Collectors.toList());

        return new PageResult(postsPage.getTotal(), sensitivePosts);
    }

    @Override
    @Transactional
    public void deletePost(Integer postId) {
        // 1. 先获取文章信息（用于后续更新分类计数）
        Posts post = getById(postId);
        if (post == null) {
            throw new RuntimeException("文章不存在");
        }

        // 2. 检查并删除相关评论
        LambdaQueryWrapper<Comments> commentsWrapper = new LambdaQueryWrapper<>();
        commentsWrapper.eq(Comments::getPostId, postId);
        if (commentsMapper.selectCount(commentsWrapper) > 0) {
            commentsMapper.delete(commentsWrapper);
        }

        // 3. 检查并删除相关收藏
        LambdaQueryWrapper<Favorites> favoritesWrapper = new LambdaQueryWrapper<>();
        favoritesWrapper.eq(Favorites::getPostId, postId);
        if (favoritesMapper.selectCount(favoritesWrapper) > 0) {
            favoritesMapper.delete(favoritesWrapper);
        }

        // 4. 检查并删除相关点赞
        LambdaQueryWrapper<Likes> likesWrapper = new LambdaQueryWrapper<>();
        likesWrapper.eq(Likes::getPostId, postId);
        if (likesMapper.selectCount(likesWrapper) > 0) {
            likesMapper.delete(likesWrapper);
        }

        // 5. 检查并删除相关敏感词记录
        LambdaQueryWrapper<SensitiveWordRecord> sensitiveWrapper = new LambdaQueryWrapper<>();
        sensitiveWrapper.eq(SensitiveWordRecord::getContentId, postId);
        if (sensitiveWordRecordMapper.selectCount(sensitiveWrapper) > 0) {
            sensitiveWordRecordMapper.delete(sensitiveWrapper);
        }

        // 6. 删除文章本身
        removeById(postId);

        // 7. 更新分类计数
        if (post.getCategoryId() != null) {
            categoriesService.subCount(Long.valueOf(post.getCategoryId()));
        }
    }

}
